<template>
  <div class="main">
    <div class="topTitle">{{ props.title }}</div>
    <div class="form_content">
      <NScrollbar>
        <NSpin :show="spinRulesShow">
          <div class="content">
            <div style="width: 100%; display: flex; justify-content: center">
              <NForm ref="formRef" require-mark-placement="left" label-placement="left" :rules="rules" :label-width="120"
                :model="formValue" style="width: 1000rem">
                <NSpace justify="space-between">
                  <NFormItem label="规则名称:" path="workAttendanceRule.ruleName">
                    <NInput placeholder="请输入规则名称" class="commonWidth" type="text"
                      v-model:value="formValue.workAttendanceRule.ruleName" clearable :allow-input="stopNull" />
                  </NFormItem>

                  <NFormItem label="选择年份:" path="workAttendanceRule.year">
                    <NSelect placeholder="请选择年份" class="commonWidth" clearable :options="yearList"
                      v-model:value="formValue.workAttendanceRule.year" />
                  </NFormItem>
                </NSpace>

                <NSpace justify="space-between">
                  <NFormItem label="上班时间:" path="workAttendanceRule.startWorkTime">
                    <NTimePicker placeholder="请选择上班时间" class="commonWidth" clearable
                      v-model:formatted-value="formValue.workAttendanceRule.startWorkTime"
                      :is-hour-disabled="isHourDisabledStart" :is-second-disabled="isSecondDisabledStart"
                      :is-minute-disabled="isMinuteDisabledStart" />
                  </NFormItem>

                  <NFormItem label="下班时间:" path="workAttendanceRule.endWorkTime">
                    <NTimePicker placeholder="请选择下班时间" class="commonWidth" clearable
                      v-model:formatted-value="formValue.workAttendanceRule.endWorkTime"
                      :is-hour-disabled="isHourDisabled" />
                  </NFormItem>
                </NSpace>

                <NSpace justify="space-between">
                  <NFormItem label="月份选择:" path="workAttendanceRule.month">
                    <n-checkbox-group v-model:value="formValue.workAttendanceRule.month">
                      <n-space item-style="display: flex;">
                        <n-checkbox v-for="(item, index) in monthList" :key="index" :value="item.value"
                          :label="item.label" />
                      </n-space>
                    </n-checkbox-group>
                  </NFormItem>
                </NSpace>

                <NSpace justify="space-between">
                  <NFormItem label="工作日配置:" path="workAttendanceRule.week">
                    <n-checkbox-group v-model:value="formValue.workAttendanceRule.week">
                      <n-space item-style="display: flex;">
                        <n-checkbox v-for="(item, index) in workDayList" :key="index" :value="item.value"
                          :label="item.label" />
                      </n-space>
                    </n-checkbox-group>
                  </NFormItem>
                </NSpace>

                <NFormItem label=" ">
                  <div class="calendar-box">
                    <NSpin :show="spinShow">
                      <div class="top-btn">
                        <NButton style="width: 250px" type="primary" @click="createCalendar">
                          生成日历
                        </NButton>
                      </div>
                      <div class="bottom-cal">
                        <div class="calendar">
                          <n-calendar :theme-overrides="cellModalTheme" @update-value="handleCalendarSelect">
                            <template #default="{ year, month, date }">
                              <div class="main" :style="handleCalendarStyle(year, month, date)">
                                {{ date }}
                              </div>
                            </template>
                          </n-calendar>
                        </div>
                      </div>
                    </NSpin>
                  </div>
                </NFormItem>

                <NFormItem label="应用人员范围:" path="workAttendanceUserScopeList">
                  <div style="display: flex; flex-direction: column; width: 100%">
                    <NButton style="width: 115px; margin-bottom: 15rem" type="primary" ghost @click="openScope">
                      选择应用人员
                    </NButton>
                    <div class="scope" v-if="formValue.workAttendanceUserScopeList?.length">
                      <div class="userBox" v-for="(item, index) in formValue.workAttendanceUserScopeList" :key="index">
                        <div>{{ item.typeName }}</div>
                        <n-icon @click="handleScope(item.identifyingId)" style="cursor: pointe">
                          <CloseFilled />
                        </n-icon>
                      </div>
                    </div>
                  </div>
                </NFormItem>
              </NForm>
            </div>
          </div>
        </NSpin>
      </NScrollbar>
    </div>
  </div>
  <FixedAction>
    <div style="display: flex">
      <NSpace justify="start" style="flex: 0 0 42%">
        <NButton style="width: 78px; color: #5fb17f" ghost @click="goBack">

          <template #icon>
            <img :src="VBackImg" style="width: 25rem; height: 25rem" />
          </template>
          返回
        </NButton>
      </NSpace>

      <NSpace justify="center">
        <NButton type="primary" style="width: 110px" @click="confirm" :loading="loading">
          保存考勤规则
        </NButton>
      </NSpace>
    </div>
  </FixedAction>

  <NModal :auto-focus="false" v-model:show="modalVisible" @close="modalVisible = false">
    <VScope @close="modalVisible = false" @scopeSubmit="getScopeList" :defaultList="scopeList" />
  </NModal>

  <NModal :auto-focus="false" v-model:show="submitVisible" @close="submitVisible = false">
    <VDialogContent @close="submitVisible = false" @submit="submit" title="保存提示">
      <div style="width: 300rem; height: 100rem; text-align: center; line-height: 100rem">
        您确定要保存吗？
      </div>
    </VDialogContent>
  </NModal>
</template>

<script setup lang="ts">
import { ref, reactive, watch, onMounted, render, h } from 'vue'
import {
  NSpace,
  NForm,
  NInput,
  NFormItem,
  NSelect,
  NButton,
  NScrollbar,
  NModal,
  NIcon,
  useMessage,
  NTimePicker,
  NCheckboxGroup,
  NCheckbox,
  NCalendar,
  NSpin,
  NImage,
  type FormInst
} from 'naive-ui'
import router from '@/router'
import { useTagStore } from '@/stores/layout'
import FixedAction from '@/components/FixedAction.vue'
import VScope from '@/views/OA/Common/Scope.vue'
import { sendRequest } from '@/utils/api'
import type { HttpResponse } from '@/utils/http'
import type { DisModel } from '@/api/receiveOrDispatch'
import { CloseFilled } from '@vicons/material'
import { useRoute } from 'vue-router'
import VContent from './WeekContent.vue'
import VDialogContent from '@/views/OA/Common/DialogContent.vue'
import VBackImg from '@/assets/images/back.png'

const props = defineProps({
  title: { type: String, default: () => '考勤规则新增' },
  id: { type: [Number, String], default: () => null }
})
const tags = useTagStore().tags
const route = useRoute()
const message = useMessage()
const modalVisible = ref(false)
const cellModalTheme = { cellColorHover: 'none', barColor: 'none' }
const yearList = ref()
const monthList = [
  { label: '一月', value: '1' },
  { label: '二月', value: '2' },
  { label: '三月', value: '3' },
  { label: '四月', value: '4' },
  { label: '五月', value: '5' },
  { label: '六月', value: '6' },
  { label: '七月', value: '7' },
  { label: '八月', value: '8' },
  { label: '九月', value: '9' },
  { label: '十月', value: '10' },
  { label: '十一月', value: '11' },
  { label: '十二月', value: '12' }
]
const workDayList = [
  { label: '周一', value: '周一' },
  { label: '周二', value: '周二' },
  { label: '周三', value: '周三' },
  { label: '周四', value: '周四' },
  { label: '周五', value: '周五' },
  { label: '周六', value: '周六' },
  { label: '周日', value: '周日' }
]

const formValue = reactive<Record<string, any>>({
  workAttendanceRule: {
    ruleName: null, //规则名称
    year: null, //年份
    startWorkTime: null, //上班时间
    endWorkTime: null, //下班时间
    month: null, //月份
    week: null //工作日
  },
  calendarDtoList: [], //日历信息
  workAttendanceUserScopeList: [] //人员范围
})
const rules: any = {
  workAttendanceRule: {
    ruleName: {
      required: true,
      trigger: ['input', 'blur'],
      validator: (_: any, value: any) => {
        if (!value) return new Error('请输入规则名称')
        if (value.length > 100) return new Error('规则名称字数不得超过100')
        return true
      }
    },
    year: {
      required: true,
      message: '请选择年份',
      type: 'any',
      trigger: ['change', 'blur']
    },
    startWorkTime: {
      required: true,
      message: '请选择开始时间',
      type: 'any',
      trigger: ['select', 'change']
    },
    endWorkTime: {
      required: true,
      message: '请选择结束时间',
      type: 'any',
      trigger: ['select', 'change']
    },
    month: {
      required: true,
      message: '请选择月份',
      type: 'any',
      trigger: ['select', 'change']
    },
    week: {
      required: true,
      message: '请选择工作日',
      type: 'any',
      trigger: ['select', 'change']
    }
  },
  workAttendanceUserScopeList: {
    required: true,
    type: 'array',
    message: '请选择人员范围',
    trigger: ['blur', 'change','select']
  }
}
//去除空格
const stopNull = (value: string) => {
  return !value.startsWith(' ') && !value.endsWith(' ')
}
// 禁用下班时间 H
const isHourDisabled = (hour: any) => hour <= formValue.workAttendanceRule.startWorkTime.split(':')[0]
// 禁用上班时间 H
const isHourDisabledStart = (hour: any) => hour > formValue.workAttendanceRule.endWorkTime?.split(':')[0]
// 禁用上班时间 M
const isMinuteDisabledStart = (minute: any, v: any) => {
  if (v < formValue.workAttendanceRule.endWorkTime?.split(':')[0]) return false
  if (formValue.workAttendanceRule.endWorkTime?.split(':')[1] < minute) {
    return minute > (Number(formValue.workAttendanceRule.endWorkTime?.split(':')[1]))
  } else return false
}
// 禁用上班时间 S
const isSecondDisabledStart = (second: any, v: any, c: any) => {
  if (c < formValue.workAttendanceRule.endWorkTime?.split(':')[0]) return false
  if (formValue.workAttendanceRule.endWorkTime?.split(':')[1] < second) {
    return second > (Number(formValue.workAttendanceRule.endWorkTime?.split(':')[2]))
  } else return false
}
// 日历
const spinShow = ref(false)
const createCalendar = () => {
  spinShow.value = true
  if (!formValue.workAttendanceRule.month?.length)
    return message.error('请选择月份'), (spinShow.value = false)
  if (!formValue.workAttendanceRule.week?.length)
    return message.error('请选择工作日'), (spinShow.value = false)
  if (!formValue.workAttendanceRule.year)
    return message.error('请选择年份'), (spinShow.value = false)
  formValue.calendarDtoList = []
  formValue.workAttendanceRule.month.map((it: any) => {
    formValue.calendarDtoList.push(...getDaysInMonth(formValue.workAttendanceRule.year, it))
  })
  spinShow.value = false
}
// 打开发布范围
const scopeList = ref()
const openScope = () => {
  scopeList.value = formValue.workAttendanceUserScopeList
  modalVisible.value = true
}
// 发布范围选择
const getScopeList = (v: any) => {
  formValue.workAttendanceUserScopeList = v
  modalVisible.value = false
  formRef.value?.validate()
}
// 范围选择是删除
const handleScope = (id: any) => {
  const index = formValue.workAttendanceUserScopeList?.findIndex(
    (it: any) => it.identifyingId == id
  )
  formValue.workAttendanceUserScopeList.splice(index, 1)
}
// 返回
const goBack = () => {
  const index = tags.findIndex((item: any) => item.path === router.currentRoute.value.fullPath)
  tags.splice(index, 1)
  router.push({ path: '/OA/Office/checkRules' })
}
// 确定
const loading = ref(false)
const formRef = ref<FormInst | null>(null)
const confirm = () => {
  formRef.value?.validate(async (err) => {
    if (err) return (loading.value = false), (submitVisible.value = false)
    submitVisible.value = true
  })
}
// 提交
const submitVisible = ref(false)
const submit = async () => {
  loading.value = true
  if (route.query.id) {
    submitVisible.value = false
    const data = JSON.parse(JSON.stringify(formValue))
    await handleCalendarList(data)
    data.workAttendanceRule.id = route.query.id
    const [error, res] = await sendRequest<HttpResponse<DisModel>>({
      module: 'checkRules',
      api: 'rulesUpdate',
      override: {
        data: data
      }
    })
    loading.value = false
    if (error) return message.error(error.message)
    if (res.code !== 0) return message.error(res.msg)
  } else {
    submitVisible.value = false
    const data = JSON.parse(JSON.stringify(formValue))
    await handleCalendarList(data)
    const [error, res] = await sendRequest<HttpResponse<DisModel>>({
      module: 'checkRules',
      api: 'rulesSave',
      override: {
        data
      }
    })
    loading.value = false
    if (error) return message.error(error.message)
    if (res.code !== 0) return message.error(res.msg)
  }
  goBack()
}

//提交完跳转我的提交
const goSubmit = () => {
  const index = tags.findIndex((item: any) => item.path === router.currentRoute.value.fullPath)
  tags.splice(index, 1)
  if (formValue.draft) return router.push({ path: '/OA/UserCenter/Drafts' })
  router.push({ path: '/OA/UserCenter/Submit' })
}


// 处理日历信息
const handleCalendarList = (data: any) => {
  const result: any = []
  if (!data.calendarDtoList) return message.error('请生成日历')
  console.log(selectCalendar.value)
  data.calendarDtoList.map((it: any) => {
    if (data.workAttendanceRule.week?.includes(getWeekDay(it))) {
      if (selectCalendar.value.includes(it)) return result.push({ date: it, rest: false })
      result.push({ date: it, rest: true })
    } else {
      if (selectCalendar.value.includes(it)) return result.push({ date: it, rest: true })
      result.push({ date: it, rest: false })
    }
  })
  data.calendarDtoList = result

  const resultMonth: any = []
  monthList.map((it: any) => {
    data.workAttendanceRule.month.includes(it.value) ? resultMonth.push(1) : resultMonth.push(0)
  })
  data.workAttendanceRule.month = resultMonth.map((it: any) => it).join('')

  const resultWeek: any = []
  workDayList.map((it: any) => {
    data.workAttendanceRule.week.includes(it.value) ? resultWeek.push(1) : resultWeek.push(0)
  })
  data.workAttendanceRule.week = resultWeek.map((it: any) => it).join('')
}
//根据某年某月计算出具体日期
const getDaysInMonth = (year: any, month: any) => {
  const daysOfMonth = []
  month = parseInt(month, 10)
  const lastDayOfMonth = new Date(year, month, 0).getDate()
  for (let i = 1; i <= lastDayOfMonth; i++) {
    daysOfMonth.push(year + '-' + month + '-' + i)
  }
  return daysOfMonth
}
// 根据日期判断周几
const getWeekDay = function (time: string) {
  let datelist = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  return datelist[new Date(time).getDay()]
}
// 获取今年之后的五年之内年份
const handleYear = () => {
  const year = new Date().getFullYear()
  const tmp = []
  for (let i = 0; i < 5; i++) {
    tmp.push({ label: year + i, value: year + i })
  }
  yearList.value = tmp
}
// 被选择日历的背景色
const handleCalendarStyle = (year: any, month: any, date: any) => {
  const day = year + '-' + month + '-' + date
  if (
    formValue.calendarDtoList?.includes(day) &&
    formValue.workAttendanceRule.week?.includes(getWeekDay(day))
  ) {
    if (selectCalendar.value.includes(day)) return undefined
    return { backgroundColor: '#eee' }
  }
  if (selectCalendar.value.includes(day)) return { backgroundColor: '#eee' }
  return undefined
}
// 创建子节点
const handleWeek = () => {
  const A = document.querySelector('.n-calendar')
  const B = document.querySelector('.n-calendar-dates')
  const C = document.createElement('div')
  render(h(VContent), C)
  A?.insertBefore(C, B)
}
// 日历选择
const selectCalendar: any = ref([])
const handleCalendarSelect = (_: any, { year, month, date }: any) => {
  if (!formValue.calendarDtoList) return message.error('请生成日历')
  const day = year + '-' + month + '-' + date
  console.log(month)
  console.log(formValue.workAttendanceRule.month)
  if (year != formValue.workAttendanceRule.year)
    return message.error(year + '年-' + month + '月不在当前选择范围')
  if (!formValue.workAttendanceRule.month?.includes(month.toString()))
    return message.error(year + '年-' + month + '月不在当前选择范围')
  if (selectCalendar.value.includes(day)) {
    const index = selectCalendar.value.findIndex((it: any) => it == day)
    selectCalendar.value.splice(index, 1)
  } else selectCalendar.value.push(day)
}
// 获取规则详情
const spinRulesShow = ref(false)
const getRulesInfo = async () => {
  spinRulesShow.value = true
  const [error, res] = await sendRequest<HttpResponse<DisModel>>({
    module: 'checkRules',
    api: 'rulesInfo',
    uri: {
      id: props.id
    }
  })
  if (error) return message.error(error.message), (spinRulesShow.value = false)
  if (res.code !== 0) return message.error(res.msg), (spinRulesShow.value = false)
  formValue.workAttendanceUserScopeList = res.data.workAttendanceUserScopeList
  formValue.workAttendanceRule.ruleName = res.data.workAttendanceRule.ruleName
  formValue.workAttendanceRule.year = res.data.workAttendanceRule.year
  formValue.workAttendanceRule.month = []
  res.data.workAttendanceRule.month.split('').forEach((it: any, ind: any) => {
    if (it == 1) return formValue.workAttendanceRule.month.push(monthList[ind].value)
  })
  formValue.workAttendanceRule.week = []
  res.data.workAttendanceRule.week.split('').forEach((it: any, ind: any) => {
    if (it == 1) return formValue.workAttendanceRule.week.push(workDayList[ind].value)
  })
  formValue.workAttendanceRule.startWorkTime = res.data.workAttendanceRule.startWorkTime
  formValue.workAttendanceRule.endWorkTime = res.data.workAttendanceRule.endWorkTime

  formValue.calendarDtoList = res.data.calendarDtoList.map((it: any, index: any) => {
    const date = it.date.split(' ')
    if (date[0].split('-')[1] < 9) {
      const T = date[0].split('-')
      let month = 0
      if (T[1] < 10) month = T[1].split('')[1]
      else month = T[1]
      let day = 0
      if (T[2] < 10) day = T[2].split('')[1]
      else day = T[2]
      return { rest: it.rest, date: T[0] + '-' + month + '-' + day }
    }
    return { rest: it.rest, date: date[0] }
  })
  formValue.calendarDtoList.map((it: any) => {
    if (formValue.workAttendanceRule.week?.includes(getWeekDay(it.date)) && !it.rest) {
      selectCalendar.value.push(it.date)
    } else if (!formValue.workAttendanceRule.week?.includes(getWeekDay(it.date)) && it.rest) {
      selectCalendar.value.push(it.date)
    }
  })
  createCalendar()
  spinRulesShow.value = false
}

watch(
  () => props.id,
  () => {
    if (props.title == '考勤规则编辑' && props.id) getRulesInfo()
  },
  { deep: true, immediate: true }
)

onMounted(() => {
  handleWeek()
  handleYear()
})
</script>

<style scoped lang="scss">
@mixin CommonFont {
  font-size: 16rem;
  font-family: PingFangSC, PingFang SC;
  font-weight: 400;
  color: rgba(0, 0, 0, 0.85);
}

.commonWidth {
  width: 360rem;
}

.main {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  overflow: hidden;

  .topTitle {
    width: 100%;
    border-bottom: 1px solid #fff;
    padding: 15rem 20rem;
    margin-bottom: 20rem;
    @include CommonFont;
  }

  .form_content {
    width: 100%;
    height: 100%;
    padding: 0 20rem 0rem;

    .content {
      display: flex;
      align-items: center;
      flex-direction: column;
      width: 100%;
      height: 100%;
      padding: 20rem 0 180rem;
      overflow-y: scroll;
      background-color: #ebeceb;

      .scope {
        display: flex;
        flex-wrap: wrap;
        width: 100%;
        height: auto;
        min-height: 130rem;
        background: #e1e1e1;
        margin-bottom: 25rem;
        padding: 15rem 20rem;

        .userBox {
          display: flex;
          justify-content: space-between;
          align-items: center;
          width: auto;
          min-width: 150rem;
          height: 40rem;
          background-color: #fff;
          border-radius: 4rem;
          padding: 0 10rem;
          margin-right: 15rem;
          margin-bottom: 10rem;
        }
      }
    }
  }
}

.calendar-box {
  width: 100%;
  display: flex;
  flex-direction: column;

  .top-btn {
    width: 100%;
    display: flex;
    justify-content: center;
    margin-bottom: 5rem;
  }

  .bottom-cal {
    width: 100%;
    height: 400rem;
    display: flex;
    justify-content: center;

    .calendar {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      background-color: #fff;
      padding: 10rem;
      margin-top: 10rem;
    }
  }
}

.content::-webkit-scrollbar {
  display: none;
}

.scope::-webkit-scrollbar {
  display: none;
}

:deep(.n-calendar) {
  width: 100%;
  height: 100%;
}

::v-deep(.n-calendar-cell) {
  display: flex;
  flex-direction: column;
  cursor: auto;
  padding: 5rem;

  .n-calendar-date {
    display: none;

    .n-calendar-date__date {
      display: none;
    }
  }

  .main {
    display: flex;
    flex: 1;
    justify-content: center;
    align-items: center;
  }
}

::v-deep(.n-calendar-cell--current .n-calendar-date .n-calendar-date__date) {
  background-color: transparent !important;
  color: black !important;
}

:deep(.n-spin-container) {
  width: 100%;
  height: 100%;
}

:deep(.n-scrollbar-container) {
  width: 100%;
  height: 100%;
}

:deep(.n-scrollbar-content) {
  width: 100%;
  height: 100%;
}

:deep(.n-spin-content) {
  width: 100%;
  height: 100%;
}
</style>
